package com.uam.core.business;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.uam.core.business.help.*;
import com.uam.core.config.UAMConfig;
import com.uam.core.entity.model.AircraftModel;
import com.uam.core.entity.model.PolygonV1;
import com.uam.core.entity.model.TaskModel;
import com.uam.core.lk.utils.fencebuffer.BufferBase;
import com.uam.core.tool.DateUtils;
import com.uam.core.vo.CoordinateSegment;
import lombok.extern.slf4j.Slf4j;
import org.locationtech.jts.geom.*;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.util.*;

/**
 * 冲突业务逻辑
 *
 * @author Administrator
 */
@Component
@Slf4j
public class SolveConflictBusiness extends ParentBusiness {

    /**
     * 相差时间差小于这个值，有冲突
     */
    Long interval = 1000L;
    /**
     * 冲突后，解决冲突buffer区域
     */
    Integer solveBuffer = 50;

    /**
     * 线拆分成线段
     *
     * @param points
     * @param j
     * @return
     */
    private List<LineSegment> getLineSegmentList(JSONArray points, int j) {
        List<LineSegment> stringSegments = new ArrayList<>(1024);
        int row = points.size();
        for (int i = j; i < row - j; i++) {
            JSONArray one = points.getJSONArray(i);
            JSONArray two = points.getJSONArray(i + 1);
            CoordinateSegment coordinateOne = new CoordinateSegment(one.getDouble(0), one.getDouble(1), i, one.getDate(4));
            CoordinateSegment coordinateTwo = new CoordinateSegment(two.getDouble(0), two.getDouble(1), i + 1, two.getDate(4));
            LineSegment lineStringSegment = new LineSegment(coordinateOne, coordinateTwo);
            stringSegments.add(lineStringSegment);
        }
        return stringSegments;
    }

    /**
     * 线拆分成线段
     *
     * @param points
     * @param j
     * @return
     */
    private Map<String, LineSegment> getLineSegmentMap(JSONArray points, int j) throws ParseException {
        Map<String, LineSegment> map = new LinkedHashMap<>();
        int row = points.size();
        for (int i = j; i < row - j; i++) {
            JSONArray one = points.getJSONArray(i);
            JSONArray two = points.getJSONArray(i + 1);
            CoordinateSegment coordinateOne = new CoordinateSegment(one.getDouble(0), one.getDouble(1), i, one.getDate(4));
            CoordinateSegment coordinateTwo = new CoordinateSegment(two.getDouble(0), two.getDouble(1), i + 1, two.getDate(4));
            LineSegment lineStringSegment = new LineSegment(coordinateOne, coordinateTwo);
            map.put(DateUtils.parseDateToStr(coordinateOne.getTime()), lineStringSegment);

        }
        return map;
    }

    private IntersectinInfo getIntersectinInfo(Map<String, LineSegment> segmentV2, Map<String, LineSegment> segmentMap) {
        IntersectinInfo intersectinInfo = null;
        for (Map.Entry<String, LineSegment> m : segmentV2.entrySet()) {

            LineSegment d = segmentMap.get(m.getKey());
            if (d == null) {
                continue;
            }

            CoordinateSegment p0 = (CoordinateSegment) m.getValue().p0;
            CoordinateSegment p1 = (CoordinateSegment) m.getValue().p1;
            Coordinate coordinate = m.getValue().intersection(d);

            if (coordinate != null) {
                intersectinInfo = new IntersectinInfo((CoordinateSegment) d.p0, (CoordinateSegment) d.p1, p0, p1, m.getKey(), coordinate);
                System.out.println(m.getKey() + " " + p0.getIndex() + "  " + p1.getIndex() + ",");
                return intersectinInfo;
            }
        }

        return null;
    }


    /**
     * 冲突判断和解决
     *
     * @param polygonV1s 冲突的对象
     * @param points     点带时间戳
     * @param polygon    航线缓冲区域
     */
    public JSONArray conflictSolve(List<PolygonV1> polygonV1s, JSONArray points, LineString polygon, AircraftModel aircraftModel, UAMConfig config, TaskModel taskModel) throws ParseException {

        JSONArray newPoints = new JSONArray(16);
        Map<String, LineSegment> segmentMap = IntersectinTime.getLineSegmentList(points);
        Map<String, LineSegment> segmentMapNo = getLineSegmentMap(points,2);

        for (int h = 0; h < polygonV1s.size(); h++) {
            PolygonV1 p = polygonV1s.get(h);
            Map<String, LineSegment> segmentV2 = IntersectinTime.pointsToSegment(p.getPoints());

            IntersectinInfo intersectinInfo = getIntersectinInfo(segmentMapNo, segmentV2);

           //原有时间没有找到相交点,以秒为单位，进行判断是否相交
            if (intersectinInfo == null) {
                  intersectinInfo = IntersectinTime.getIntersectinInfo(segmentMap, p);
            }

            if (intersectinInfo != null) {



                JSONArray upIndexArray = points.getJSONArray(intersectinInfo.getSourceP0().getIndex() - 1);
                JSONArray endIndex = points.getJSONArray(intersectinInfo.getSourceP1().getIndex() + 1);

                CoordinateSegment coordinateOne = new CoordinateSegment(upIndexArray.getDouble(0), upIndexArray.getDouble(1), 0, null);
                CoordinateSegment coordinateTwo = new CoordinateSegment(endIndex.getDouble(0), endIndex.getDouble(1), 0, null);

                Polygon pBuffer = this.lineBuffer(new Coordinate[]{coordinateOne, coordinateTwo}, aircraftModel.getSafeDistance()+30);

                JSONArray jsonArrayTemp=new JSONArray();
                jsonArrayTemp.add(points.getJSONArray(intersectinInfo.getSourceP0().getIndex() - 3));
                jsonArrayTemp.add(upIndexArray);
                jsonArrayTemp.add(endIndex);
                jsonArrayTemp.add(points.getJSONArray(intersectinInfo.getSourceP1().getIndex() + 3));

                LineString lineString=  jsonArrayNew(jsonArrayTemp);
                JSONArray  geometryPoint = TestInfo.test(lineString, pBuffer);



                if (geometryPoint == null || geometryPoint.size()==0) {
                    //todo


                } else {
                    //左右别让
                    JSONArray routes = geometryPoint;//jsonObjectHttp.getJSONArray("paths");
                    System.out.println("冲突信息："+routes);
                        //最高层别让
//                        JSONObject newPaths = routes.getJSONObject(0).getJSONObject("points");
//                        JSONArray path = newPaths.getJSONArray("coordinates");

                        System.out.println("birang="+JSONArray.toJSONString(routes));


                        JSONArray jsonArrayNew=new JSONArray(1024);


                    int row= intersectinInfo.getSourceP0().getIndex()-3;
                    for(int i=0;i<row;i++){
                        JSONArray jsonArray= points.getJSONArray(i);
                        jsonArray.remove(3);
                        if(jsonArray.size() ==4) {
                            jsonArray.remove(3);
                        }
                        jsonArrayNew.add(jsonArray);
                    }

                    jsonArrayNew.addAll(routes);

                    for(int i=intersectinInfo.getSourceP1().getIndex()+3;i<points.size();i++){
                        JSONArray jsonArray= points.getJSONArray(i);
                        jsonArray.remove(3);
                        if(jsonArray.size() ==4) {
                            jsonArray.remove(3);
                        }
                        jsonArrayNew.add(jsonArray);
                    }



                        points.clear();
                        points.addAll(jsonArrayNew);
                        //重新计算时间
                        getHistoryTime(points, aircraftModel.getSpeed(), taskModel, 0, true);
                        newPoints.add(p.getTaskId());
                    }
            }
        }
        return newPoints;
    }

    private JSONArray jsonArrayNew(JSONArray jsonArray, int start, int end) {
        JSONArray jsonArrayNew = new JSONArray(1024);
        for (int i = start; i < end; i++) {
            jsonArrayNew.add(jsonArray.getJSONArray(i));
        }
        return jsonArrayNew;
    }

    private Map<String, Object> reqParam(Polygon pBuffer, JSONArray upIndexArray, JSONArray endIndexArray, AircraftModel aircraftModel) {
        Map<String, Object> paramMap = new HashMap<>(16);
        paramMap.put("profile", "car");
        paramMap.put("elevation", true);
        paramMap.put("instructions", true);
        paramMap.put("locale", "zh_CN");
        paramMap.put("optimize", true);
        paramMap.put("points_encoded", false);
        paramMap.put("alternative_route.max_paths", 3);
        paramMap.put("type", "orsm");
        paramMap.put("ch.disable", true);
        paramMap.put("max_height", aircraftModel.getMaxAltitude());
        paramMap.put("min_height", aircraftModel.getMinAltitude());
        paramMap.put("flight_type", 0);


        JSONObject jsonObject = new JSONObject();
        jsonObject.put("points", lineBuffer.gpsToString(pBuffer.getCoordinates()));
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(jsonObject);


        paramMap.put("obstacle_vos", jsonArray);
        List<Double[]> jsonPathList = new ArrayList<>();
        Double[] arr = new Double[2];
        arr[0] = upIndexArray.getDouble(0);
        arr[1] = upIndexArray.getDouble(1);
        jsonPathList.add(arr);


        Double[] arrEnd = new Double[2];
        arrEnd[0] = endIndexArray.getDouble(0);
        arrEnd[1] = endIndexArray.getDouble(1);
        jsonPathList.add(arrEnd);

        paramMap.put("points", jsonPathList);
        return paramMap;
    }

    private Map<String, Object> reqParam(Polygon pBuffer, com.mapbox.geojson.Point upIndexArray, com.mapbox.geojson.Point endIndexArray, AircraftModel aircraftModel) {
        Map<String, Object> paramMap = new HashMap<>(16);
        paramMap.put("profile", "car");
        paramMap.put("elevation", true);
        paramMap.put("instructions", true);
        paramMap.put("locale", "zh_CN");
        paramMap.put("optimize", true);
        paramMap.put("points_encoded", false);
        paramMap.put("alternative_route.max_paths", 3);
        paramMap.put("type", "orsm");
        paramMap.put("ch.disable", true);
        paramMap.put("max_height", aircraftModel.getMaxAltitude());
        paramMap.put("min_height", aircraftModel.getMinAltitude());
        paramMap.put("flight_type", 0);


        JSONObject jsonObject = new JSONObject();
        jsonObject.put("points", lineBuffer.gpsToString(pBuffer.getCoordinates()));
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(jsonObject);


        paramMap.put("obstacle_vos", jsonArray);
        List<Double[]> jsonPathList = new ArrayList<>();
        Double[] arr = new Double[2];
        arr[0] = upIndexArray.longitude();
        arr[1] = upIndexArray.latitude();
        jsonPathList.add(arr);


        Double[] arrEnd = new Double[2];
        arrEnd[0] = endIndexArray.longitude();
        arrEnd[1] = endIndexArray.longitude();
        jsonPathList.add(arrEnd);

        paramMap.put("points", jsonPathList);
        return paramMap;
    }
}
